home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
IRIS Performer 2.2 Friends Demo
/
SGI IRIS Performer 2.2 Friends Demo.iso
/
friends
/
medit
/
pfLoader
/
Internalstuff
/
oldfiles.c
< prev
next >
Wrap
Text File
|
1997-11-20
|
17KB
|
732 lines
/************************************************************************
Stuff to help us convert older files into new files
************************************************************************/
/* --- Sub object structure --- */
#define SOS struct sub_object_struct
typedef SOS {
SOS *Next; /* Points to next sub object in object */
char *Name; /* Name of sub object */
int Id; /* Id (used during file operations */
PolygonPtr FirstPolygon; /* First polygon in this sub object */
int Flag; /* A useful flag */
} SubObject;
typedef SubObject *SubObjectPtr;
#undef SOS
SubObjectPtr SubObjectList = NULL;
/* these don't exist any more */
enum { Unlit=0, Lit, Smooth };
#define FPLighting FPSmooth
#define FPTextureMat FPUnused
/************************************************************************
Add a child to a tree branch (at the bottom of the list)
************************************************************************/
static void AddChild(TreePtr parent, TreePtr newchild)
{
reg TreePtr t = parent;
if (t->Across) {
t = t->Across;
while (t->Down) {
t = t->Down;
}
t->Down = newchild;
newchild->Down = NULL;
#if ITSTHEMODELLER
newchild->Up = t;
newchild->Across = NULL;
newchild->Back = NULL;
#endif
}
else {
t->Across = newchild;
newchild->Down = NULL;
#if ITSTHEMODELLER
newchild->Up = NULL;
newchild->Across = NULL;
newchild->Back = t;
#endif
}
}
/************************************************************************
File revision 1.00 (ascii file, single object, no heirarchy)
************************************************************************/
static float (*VertexList100)[XYZ];
#if !ITSTHEMODELLER
#define MaxFileLine 1000
static char FileData[MaxFileLine],*RestOfLine;
static boolean ReadLineFromFile(FILE *f)
{
reg char c,*s;
if (fgets(FileData,MaxFileLine,f) ISNT 0) {
c = *(s = FileData); /* Remove trailing '\n' */
until ((c IS '\0') OR (c IS '\n')) {
c = *++s;
}
*s = '\0';
return TRUE;
}
else {
return FALSE;
}
}
#endif
static boolean GetModelHeader100(FILE *f, char *Match, int *Count)
{
float compatibility;
if ((sscanf(FileData,Match,&compatibility) ISNT 1) OR (compatibility ISNT 1.00)) {
SetError(BAD_FILE);
return FALSE;
}
if (ReadLineFromFile(f)) {
if (sscanf(FileData,"Count: %d",Count) IS 1) {
return TRUE;
}
}
SetError(BAD_FILE);
return FALSE;
}
static boolean GetVertices100(FILE *f)
{
int i,count;
float x,y,z;
if (!GetModelHeader100(f,"Vertices (v%f)",&count)) {
return FALSE;
}
VertexList100 = Allocate(count * sizeof(float) * XYZ);
for (i=0; i<count; i++) {
if (fscanf(f,"%f %f %f\n",&x,&y,&z) ISNT 3) {
SetError(BAD_FILE);
return FALSE;
}
VertexList100[i][X] = x;
VertexList100[i][Y] = -z;
VertexList100[i][Z] = y;
}
return TRUE;
}
static boolean GetPolygons100(FILE *f, TreePtr pnode)
{
real c[XYZ];
PolygonPtr p;
PolygonBeadPtr pb;
int i, j, lighting;
int count, v, verts, mat;
if (!GetModelHeader100(f,"Polygons (v%f)",&count)) {
return FALSE;
}
*CurrentMaterial() = NULL;
for (i=0; i<count; i++) {
if ((fscanf(f," Material:%d", &mat) ISNT 1)
OR (fscanf(f," Shading:%d", &lighting) ISNT 1)
OR (fscanf(f," Sides:%d - Vertices ", &verts ) ISNT 1) ) {
SetError(BAD_FILE);
return FALSE;
}
CurrentSmoothing = (lighting IS Smooth);
pb = NULL;
for (j=0; j<verts; j++) {
if (fscanf(f,"%d ",&v) ISNT 1) {
SetError(BAD_FILE);
return FALSE;
}
CopyXYZ(c, VertexList100[v]);
AddPolygonBead(&pb, c);
}
fscanf(f,"\n");
p = AddPolygon(pb,pnode,NULL);
p->Flag = mat;
}
return TRUE;
}
#define M(x) m->x+0,m->x+1,m->x+2
static boolean GetMaterials100(FILE *f, TreePtr t)
{
flag used;
PolygonPtr p;
MaterialPtr m;
int i, no, count;
if (!GetModelHeader100(f,"Materials (v%f)",&count)) {
return FALSE;
}
m = NULL;
for (i=0; i<count; i++) {
if (fscanf(f,"Material %d: ",&no) ISNT 1) {
return FALSE;
}
if (!m) {
m = NewMaterial();
}
ReadLineFromFile(f);
RenameMaterial(m, FileData);
if (fscanf(f,"RA:%f GA:%f BA:%f\n",M(Ambient)) ISNT 3) return FALSE;
if (fscanf(f,"RD:%f GD:%f BD:%f\n",M(Diffuse)) ISNT 3) return FALSE;
if (fscanf(f,"RS:%f GS:%f BS:%f\n",M(Specular)) ISNT 3) return FALSE;
if (fscanf(f,"Shine: %f\n",&(m->Shine)) ISNT 1) return FALSE;
used = FALSE;
LoopThroughBranchesPolygons(t, p) {
if (p->Flag IS i) {
used = TRUE;
p->Material = m;
}
}
if (used) {
AddMaterial(m);
m = NULL;
}
}
if (m) {
FreeMaterial(m);
}
*CurrentMaterial() = *FirstMaterial();
return TRUE;
#undef M
}
#define EX(x) (CurrentName + strlen(CurrentName) - strlen(x))
void ReadModel100(FILE *f, char *fname)
{
reg TreePtr pnode;
reg ModelObjectPtr o;
char name[MaxFileName], *n;
reg flag GotVertices, GotPolygons, GotMaterials;
strcpy(name,fname); /* Generate name for object */
if (!strcmp(name + strlen(name) - strlen(FileExtension), FileExtension)) {
*(name + strlen(name) - strlen(FileExtension)) = '\0';
}
n = name;
while (strchr(n, '/')) {
n = strchr(n, '/') + 1;
}
o = AddObject(n); /* Basic object structure */
pnode = NewTreeBranch(PolygonBranch, n);
o->Tree = NewTreeBranch(GroupBranch, NULL);
AddChild(o->Tree, pnode);
VertexList100 = NULL; /* Read the file */
GotVertices = GotPolygons = GotMaterials = FALSE;
while (!FileError AND ReadLineFromFile(f)) {
if (!strncmp(FileData,"Ver",3)) {
GotVertices = GetVertices100(f);
}
else if (!strncmp(FileData,"Pol",3)) {
GotPolygons = GetPolygons100(f, pnode);
}
else if (!strncmp(FileData,"Mat",3)) {
GotMaterials = GetMaterials100(f, pnode);
}
}
if (FileError && (FileErrorType IS REACHED_END)) {
if (GotVertices && GotPolygons && GotMaterials) {
FileError = FALSE;
*CurrentMaterial() = NULL;
}
}
if (VertexList100) {
Free(VertexList100);
}
}
/************************************************************************
Read/write shorts...
************************************************************************/
static boolean GetShort(reg FILE *f, reg int *Result)
{
if (!FileError) {
int b1,b2;
if (!GetByte(f,&b1) OR !GetByte(f,&b2)) {
SetError(BAD_FILE);
return FALSE;
}
else {
*Result = (b1<<8) + b2;
return TRUE; /* Ok */
}
}
else {
return FALSE;
}
}
/************************************************************************
Pre 4.0 vertices...
************************************************************************/
static int VListSize = 0;
static real (*VListBase)[XYZ];
static void ReadOldVertices(FILE *f)
{
int i,count;
GetStuff(GetInt(f,&count));
if (count > VListSize) {
if (!VListSize) {
VListBase = malloc(count*XYZ*sizeof(real));
}
else {
VListBase = realloc(VListBase, count*XYZ*sizeof(real));
}
VListSize = count;
}
for (i=0; i<count; i++) {
GetStuff(GetReals(f,VListBase[i],XYZ));
TwistReal(VListBase[i]);
}
}
static void ReadOldVertex(FILE *f, PolygonPtr p)
{
real c[XYZ];
int token, index;
flag HadCoord = FALSE;
PolygonBeadPtr lastpb = NULL;
while (GetByte(f,&token)) {
switch (token) {
case BlockEnd: return;
case FVCoord: if (HadCoord) {
SetError(BAD_VERTEX);
}
else {
HadCoord = TRUE;
GetStuff(GetReals(f,c,XYZ));
TwistReal(c);
lastpb = AddPolygonBead(&(p->FirstBead),c);
}
break;
case FVIndex: if (HadCoord) {
SetError(BAD_VERTEX);
}
else {
HadCoord = TRUE;
if (!VListBase) {
SetError(BAD_VERTEX);
}
GetStuff(GetInt(f, &index));
if ((index < 0) OR (index >= VListSize)) {
SetError(BAD_VERTEX_INDEX);
}
else {
lastpb = AddPolygonBead(&(p->FirstBead),VListBase[index]);
}
}
break;
case FVTexture: if (lastpb) {
GetStuff(GetFloats(f,lastpb->TextureCoord,XY));
}
else {
SetError(BAD_VERTEX);
}
break;
case FVNormal: if (lastpb) {
GetStuff(GetFloats(f,lastpb->Normal,XYZ));
TwistFloat(lastpb->Normal);
}
else {
SetError(BAD_VERTEX);
}
FileHadNormals = TRUE;
break;
default: if (!SkipFuture(f)) {
SetError(BAD_VERTEX);
}
}
}
}
/************************************************************************
Pre 4.0 polygons
************************************************************************/
static void ReadOldPolygon(reg FILE *f, PolygonPtr parent)
{
int token, data;
reg MaterialPtr m;
reg PolygonPtr p = NewPolygon();
if (parent) {
p->Next = parent->Child;
parent->Child = p;
}
else {
p->Next = SubObjectList->FirstPolygon;
SubObjectList->FirstPolygon = p;
}
while (GetByte(f,&token)) {
switch (token) {
case BlockEnd: if (p->Coloured) {
m = p->Material;
p->Colour = ((lcolour)(m->Diffuse[0]*255)) << 16;
p->Colour |= ((lcolour)(m->Diffuse[1]*255)) << 8;
p->Colour |= ((lcolour)(m->Diffuse[2]*255));
p->Colour |= ((lcolour)(m->Alpha *255)) << 24;
p->Material = NULL;
}
return;
case FPolygon: ReadOldPolygon(f,p);
break;
case FPMaterial: if (Compatibility < 3.00) {
GetStuff(GetByte(f,&data));
}
else {
GetStuff(GetShort(f,&data));
}
p->Material = MaterialList[data];
break;
case FPLighting: GetStuff(GetByte(f,&data));
switch (data) {
case Unlit: p->Coloured = TRUE;
p->Smooth = FALSE;
break;
case Lit: p->Coloured = FALSE;
p->Smooth = FALSE;
break;
case Smooth:p->Coloured = FALSE;
p->Smooth = TRUE;
break;
}
break;
case FPNormal: GetStuff(GetFloats(f,p->Normal,XYZ));
TwistFloat(p->Normal);
FileHadNormals = TRUE;
break;
case FPTexture: GetStuff(GetInt(f,&data));
p->Texture = TextureList[data];
break;
case FPTextureMat: if (Compatibility < 3.00) {
GetStuff(GetByte(f,&data));
}
else {
GetStuff(GetShort(f,&data));
}
p->Material = MaterialList[data];
break;
case FPLightGroup: GetStuff(GetInt(f,&(p->LightGroup)));
break;
case FPEnvmapped: GetStuff(GetByte(f,&data));
p->Envmapped = (data&1) ISNT 0;
break;
case FVertex: ReadOldVertex(f, p);
break;
default: if (!SkipFuture(f)) {
SetError(BAD_POLYGON);
}
}
}
}
/************************************************************************
SubObjects...
************************************************************************/
static SubObjectPtr FindSubObject(int id, char *name)
{
reg SubObjectPtr s = SubObjectList;
while (s) {
if (name) {
if (!strcmp(name, s->Name)) {
return s;
}
}
else if (s->Id IS id) {
return s;
}
s = s->Next;
}
SetError(BAD_SUB_OBJECT);
return NULL;
}
static void TrashChildren(reg PolygonPtr p)
{
reg PolygonPtr next;
while (p) {
next = p->Next;
if (p->Child) {
TrashChildren(p->Child);
}
TrashPolygon(p);
p = next;
}
}
static void FreeSubObjects(void)
{
reg PolygonPtr p, nextp;
reg SubObjectPtr next, s = SubObjectList;
while (s) {
next = s->Next;
p = s->FirstPolygon;
while (p) {
nextp = p->Next;
if (p->Child) {
TrashChildren(p->Child);
}
TrashPolygon(p);
p = nextp;
}
Free(s->Name);
Free(s);
s = next;
}
SubObjectList = NULL;
}
static void ReadSubObject(FILE *f)
{
int token;
SubObjectPtr new;
char name[MaxName];
new = Allocate(sizeof(SubObject));
new->Next = SubObjectList;
SubObjectList = new;
GetString(f,name,MaxName);
new->Name = CopyOfString(name);
new->FirstPolygon = NULL;
while (GetByte(f,&token)) {
switch (token) {
case BlockEnd: return;
case FSubObjectId: GetInt(f,&(SubObjectList)->Id);
break;
case FVList: ReadOldVertices(f);
break;
case FPolygon: ReadOldPolygon(f,NULL);
break;
default: if (!SkipFuture(f)) {
SetError(BAD_SUB_OBJECT);
}
}
}
}
static void GetPolysFromSubObject(TreePtr lod, SubObjectPtr s)
{
char *n;
TreePtr t;
PolygonPtr new, p;
p = s->FirstPolygon;
n = strstr(s->Name, "SubObject")? NULL: s->Name;
t = NewTreeBranch(PolygonBranch, n);
while (p) {
new = CopyOfPolygon(p);
LinkPolygon(new, t, NULL);
p = p->Next;
}
AddChild(lod, t);
}
static void ReadLod(FILE *f, ModelObjectPtr o)
{
TreePtr lod;
SubObjectPtr s;
float switchout;
char name[MaxName];
int token, id, value;
GetString(f,name,MaxName);
lod = NewTreeBranch(LodBranch, name);
if (!o->Tree) {
o->Tree = NewTreeBranch(GroupBranch, NULL);
}
AddChild(o->Tree, lod);
while (GetByte(f,&token)) {
switch (token) {
case BlockEnd: return;
case FSwitchOut: GetFloats(f,&switchout,1);
lod->SwitchOut = fabs(switchout);
break;
case FSubObject: GetString(f,name,MaxName);
if (s = FindSubObject(-1, name)) {
GetPolysFromSubObject(lod, s);
}
else {
SetError(SUB_OBJECT_NOT_FOUND);
}
break;
case FBeadVisible: GetStuff(GetInt(f, &value));
#if ITSTHEMODELLER
lod->EyeOpen = value;
#endif
break;
case FSubObjectId: GetStuff(GetInt(f,&id));
if (s = FindSubObject(id, NULL)) {
GetPolysFromSubObject(lod, s);
}
else {
SetError(SUB_OBJECT_NOT_FOUND);
}
break;
default: if (!SkipFuture(f)) {
SetError(BAD_LOD);
}
}
}
}
/************************************************************************
Read the scene tree...
************************************************************************/
static void ReadScene(FILE *f, TreePtr parent)
{
TreePtr new;
int token, n;
char name[MaxFileName];
GetString(f,name,MaxFileName);
new = NewTreeBranch(GroupBranch, name);
AddChild(parent, new);
while (GetByte(f,&token)) {
switch (token) {
case FPop: return;
case FPush: ReadScene(f,new);
break;
case FBranch: if (GetString(f,name,MaxFileName)) {
new = NewTreeBranch(GroupBranch, name);
AddChild(parent, new);
}
else {
SetError(BAD_TREE);
}
break;
case FInstance: new->Type = InstanceBranch;
GetStuff(GetInt(f, &(new->ObjId)));
break;
case FMatrix: GetStuff(GetMatrix(f,new->Transformation));
break;
case FVisible: GetStuff(GetInt(f, &n));
#if ITSTHEMODELLER
new->EyeOpen = n;
#endif
break;
case FFolded: GetStuff(GetInt(f, &n));
#if ITSTHEMODELLER
new->Folded = n;
#endif
break;
default: if (!SkipFuture(f)) {
SetError(BAD_TREE);
}
}
}
}
static ModelObjectPtr OldScene;
static void ReadOldScene(FILE *f)
{
OldScene = AddObject("Scene");
OldScene->Id = -1; /* This id can't exist normally... */
OldScene->IsTopLevel = TRUE;
OldScene->Tree = NewTreeBranch(GroupBranch, "Scene");
ReadScene(f, OldScene->Tree);
}
#if ITSTHEMODELLER
static void DealWithSceneView(reg int id, reg ViewPtr view)
{
if (OldScene) {
*CurrentObject() = OldScene;
if ((id >= 0x200) AND (id < (0x200+NoViews))) {
CopyView(DefaultObject2D(id-0x200),view);
}
else if (id IS 0x23d) {
CopyView(DefaultObject3D(),view);
}
else if ((id >= 0x300) AND (id < (0x300+MaxViewports))) {
CopyView(ObjectView(id-0x300),view);
}
}
}
static void RememberSceneGridIndex(int n)
{
if (OldScene) {
*CurrentObject() = OldScene;
*GridIndex() = n;
}
}
static void RememberSceneGridSteps(int n)
{
if (OldScene) {
*CurrentObject() = OldScene;
*GridSteps() = n;
}
}
#endif
/************************************************************************
Set billboard attribute
************************************************************************/
static void SetBillboarding(reg TreePtr t)
{
while (t) {
if (t->Type IS PolygonBranch) {
t->Billboard = TRUE;
}
if (t->Across) {
SetBillboarding(t->Across);
}
t = t->Down;
}
}
/************************************************************************
Remove pointless LODs from old files
************************************************************************/
void RemoveEmptyLods(ModelObjectPtr o)
{
reg TreePtr l;
if (o->Tree) {
l = o->Tree->Across;
if ((l->Type IS LodBranch) AND l->Across AND !l->Down) {
if (l->SwitchOut > 999999) { /* Default switch distance */
#if ITSTHEMODELLER
l->Back->Across = l->Across;
l->Across->Back = l->Back;
#else
o->Tree->Across = l->Across;
#endif
l->Across = NULL;
FreeTree(l);
}
}
}
}
/************************************************************************
Read original texture directory...
************************************************************************/
static void ReadTextureDir(FILE *f)
{
char junk[MaxFileName];
GetString(f,junk,MaxFileName);
}